#include "Entrada.h"

Entrada::Entrada(int id, Semaforo *lectura, Semaforo *escritura,
		Semaforo * terminar) {
	this->id = id;
	this->entradaDeAutos = new Fifo(Utils::NOMBRE_ARCHIVO_ENTRADA);
	this->semaforoLectura = lectura;
	this->semaforoEscritura = escritura;
	this->simulacionHandler = new SimulacionHandler();
	this->terminar = terminar;
	SignalHandler::getInstance()->registrarHandler(SIGINT,
			this->simulacionHandler);
}

void Entrada::iniciar(Estacionamiento* estacionamiento) {
	int procId;
	while (this->simulacionHandler->getGracefulQuit() == 0) {
		Auto autoEntrando;
		this->semaforoLectura->p();
		if (this->simulacionHandler->getGracefulQuit() == 0) {
			//cout << "La Entrada : " << getId()
			//	<< " esta esperando el ingreso de un auto" << endl;
			int resultado = this->entradaDeAutos->leer((char*) &autoEntrando,
					sizeof(Auto));
			if (resultado != 0) {
				int pos = estacionamiento->getPosicionLibre();
				if (pos != -1) {
					estacionamiento->estaciona(&autoEntrando);
					procId = fork();
					if (procId == 0) {
						autoEntrando.setPos(pos);
						autoEntrando.estacionar();
						autoEntrando.salir();
						estacionamiento->sacarAuto(&autoEntrando);
						estacionamiento->liberarMemoria();
						break;
					}
				} else {
					cout << "Vino el auto : " << autoEntrando.getId()
							<< " pero no hay lugar en el estacionamiento"
							<< endl;
				}
			} else {
				cout << "Error al leer en Entrada: " << this->getId() << endl;
			}
		}
		if (procId != 0)
			this->semaforoEscritura->v();
	}
	if (procId != 0) {
		cout << "La entrada " << getId() << " finaliza" << endl;
		this->terminar->v();
	}
	this->entradaDeAutos->cerrar();
}

int Entrada::getId() {
	return this->id;
}

Entrada::~Entrada() {
	SignalHandler::getInstance()->removerHandler(SIGINT);
	SignalHandler::destruir();
	this->entradaDeAutos->cerrar();
	delete this->simulacionHandler;
	delete this->entradaDeAutos;
}

